<template>
  <div id="app">
  <div class="col-8 offset-2">
    <table class="table caption-top table-hover table-striped">
      <caption class="text-center">
        <h1>基于阶段的缺陷预计模型</h1>

        <el-button type="primary" round @click="getStudents">get</el-button>

        <el-button type="warning" @click="dialogVisible = true">新增试验</el-button>

        <el-input type="text" placeholder="test_name" class="w-25" v-model="serach_name"></el-input><el-button type="success" @click="search">searching</el-button>

        <el-dialog
          title="添加新试验"
          :visible.sync="dialogVisible"
          width="30%"
          :before-close="handleClose">
          <span>New Test Data</span>
          <span slot="footer" class="dialog-footer">
            <el-button @click="dialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="addstudent">add</el-button>
          </span>
          <div><span>序号</span><input v-model="newstudents.id"/></div>
          <div><span>软件型号</span><input v-model="newstudents.name"/></div>
          <div><span>初步设计</span><input v-model.number="newstudents.stage1"/></div>
          <div><span>详细设计</span><input v-model.number="newstudents.stage2"/></div>
          <div><span>编码</span><input v-model.number="newstudents.stage3"/></div>
          <div><span>单元测试</span><input v-model.number="newstudents.stage4"/></div>
          <div><span>集成测试</span><input v-model.number="newstudents.stage5"/></div>
          <div><span>系统测试</span><input v-model.number="newstudents.stage6"/></div>
        </el-dialog>

        <el-button  @click="dialogVisiblelogin = true">登录</el-button>
        <el-dialog
          title="login"
          :visible.sync="dialogVisiblelogin"
          width="30%"
          :before-close="handleClose">
          <span>user</span>
          <input type="text" v-model="user.username">
          <br>
          <span>password</span>
          <input type="password" v-model="user.password">
          <span slot="footer" class="dialog-footer">
            <el-button @click="dialogVisiblelogin = false">取 消</el-button>
            <el-button type="primary" @click="login">登录</el-button>
          </span>
        </el-dialog>

        <el-button  @click="dialogVisibleregister = true">注册</el-button>
        <el-dialog
          title="Register"
          :visible.sync="dialogVisibleregister"
          width="30%"
          :before-close="handleClose">
          <span>user</span>
          <input type="text" v-model="register_data.username">
          <br>
          <span>password</span>
          <input type="password" v-model="register_data.password">  
          <br>
          <span>confirm_password</span>
          <input type="password" v-model="register_data.confirm_password">  
          <span slot="footer" class="dialog-footer">
            <el-button @click="dialogVisibleregister = false">取 消</el-button>
            <el-button type="primary" @click="register">注册</el-button>
          </span>
        </el-dialog>
      </caption>
  <thead>
    <tr>
      <th scope="col" >序号</th>
      <th scope="col" >软件型号</th>
      <th scope="col" >初步设计</th>
      <th scope="col" >详细设计</th>
      <th scope="col" >编码</th>
      <th scope="col" >单元测试</th>
      <th scope="col" >集成测试</th>
      <th scope="col" >系统测试</th>
      <th scope="col" >操作</th>
    </tr>
  </thead>
  <tbody>
    <Student v-for="stu in student_for_page":key="stu.id" :tostudent="stu"></Student>
    <!--这个 v-for 指令用于循环渲染一个列表中的每个元素。在这里，它会遍历 student_for_page 数组，为每个学生生成一个 Student 组件实例。 !-->
    <!--:key="stu.id" 用于为每个生成的组件提供唯一的标识，这在 Vue 的虚拟 DOM 中用于高效地更新和重排元素。 !-->
    <!--:tostudent="stu" 将每个学生对象作为 tostudent 属性传递给 Student 组件。组件可以对tostudent进行调用 !-->
    <!--局部更新：当子组件的 tostudent 发生变化时，Vue 的响应式系统会确保只更新那些真正发生变化的 DOM 元素。因此，父组件的 <tbody> 不会整个重新渲染，而是局部更新。 !-->
    <!--只有那些与被修改对象相关的 DOM 元素（如某一行中的某个 <td>）会被更新。整体不变：Vue 非常高效地处理这种情况，只更新必要的部分，不会无谓地重新渲染整个 <tbody>，避免了性能问题。 !-->
  </tbody>
</table>
  <div class="text-center">
    <el-button-group>
      <el-button type="primary" icon="el-icon-arrow-left" @click="last_page">上一页</el-button>
      <el-button type="primary" @click="next_page">下一页<i class="el-icon-arrow-right el-icon--right"></i></el-button>
    </el-button-group>
  </div>
  <div><br><br></div>
 <table class="table caption-top table-hover table-striped">
    <thead>
    <tr>
      <th scope="col" >序号</th>
      <th scope="col" >软件型号</th>
      <th scope="col" >峰值位置T_min</th>
      <th scope="col" >缺陷总数E(B_min)</th>
      <th scope="col" >潜在缺陷数L</th>
      <th scope="col" >缺陷发现率EFF</th>
    </tr>
  </thead>
    <tbody>
      <tr>
        <td>{{Results.id}}</td>
        <td>{{Results.name}}</td>
        <td>{{Results.t}}</td>
        <td>{{Results.e}}</td>
        <td>{{Results.l}}</td>
        <td>{{Results.eff}}</td>
      </tr>
  </tbody>
</table>
<div class="echart" id="mychart" :style="myChartStyle"></div>
  </div>
  </div>
</template>

<script>
import axios from 'axios'
import * as echarts from "echarts";
import Student from './components/Student' 
export default {
  name: 'App',
  components: {
    Student 
  },
  data(){
    return{
      serach_name:"",
      user:{
        username:"",
        password:"",
      },
      register_data:{
        username:"",
        password:"",
        confirm_password:"",
      },
      page:1,
      students:[],
      Results:{
        id:"",
        name:"",
        t:"",
        e:"",
        l:"",
        eff:"",
        dv:{dv1:"",dv2:"",dv3:"",dv4:"",dv5:"",dv6:"",},
      },
      newstudents:{
        id:"",
        name:"",
        stage1:"",
        stage2:"",
        stage3:"",
        stage4:"",
        stage5:"",
        stage6:"",
      },
      dialogVisible: false,
      dialogVisiblelogin: false,
      dialogVisibleregister: false,
      myChartStyle: { float: "left", width: "100%", height: "400px"}
    };
  },
  mounted(){
    window.getStudents= this.getStudents;  //当vue实例被创建后，通过el属性指定的dom元素会被vue管理，mounted方法表示vue实例已经成功和dom元素进行绑定
    //在这个钩子中，你将组件的 getStudents 方法赋值给了 window.getStudents。
    //这意味着你可以在全局范围内（例如在浏览器的开发者工具控制台）直接调用 getStudents() 方法如window.getStudents();这个方法会引用当前 Vue 组件实例的 getStudents 方法。
  },
  created() {
    this.$nextTick(() => {
      this.updateresult();
    });
    //数据初始化：created() 是用于在组件实例被创建时进行数据初始化或执行一些准备工作。此时组件的 data、props 等已经可用，你可以在这个阶段进行数据的获取、初始值的设置等操作。
    //created() 钩子在 DOM 渲染和挂载之前执行，适合用于初始化数据或发起请求，而 mounted() 则在组件挂载完成之后调用，适合进行需要 DOM 的操作。
    //created() 钩子被用来在组件创建后立即调用 updateresult() 方法，目的是初始化 Results 数据。然而，由于 updateresult() 依赖于参数 re，如果没有传入这个参数，方法可能不会按照预期工作
  },
  methods:{
    getStudents(){
      if(sessionStorage.getItem("isLogined")=="true"){
        axios({
          url:"http://localhost:8080/students",
          method:'GET',
        }).then(res=>{
          console.log(res.data);
          this.students=res.data;
        })    
      }else{
        this.$alert("Please login first!")
      }

    },
    handleClose(done) {
      this.$confirm('确认关闭？')
        .then(_ => {
          done();
        })
        .catch(_ => {});
    },
    addstudent(){
      axios({
        url:"http://localhost:8080/add",
        method:'POST',
        data:this.newstudents
      })
      this.dialogVisible = false
    },
    next_page(){
      this.page+=1;
    },
    last_page(){
      this.page-=1;
    },
    login(){
      axios({
        url:"http://localhost:8080/login",
        data:this.user,
        method:"POST"
      }).then(res=>{
        console.log(res.data);
        if(res.data==1){
          sessionStorage.setItem("isLogined","true");
        }
        else{
          alert("username/password wrong!");
        }
      })
      this.dialogVisiblelogin=false
    },
    register(){
      if(this.register_data.password==this.register_data.confirm_password){
          axios({
          url:"http://localhost:8080/register",
          data:this.register_data,
          method:"POST"
        }).then(res=>{
          console.log(res.data);
          this.$alert(res.data)    //alert(res.data)
          })
        this.dialogVisibleregister=false;
      }else{
        this.$alert("password dosn't compare to confirm_password!")
      }
    },
    search(){
      if(sessionStorage.getItem("isLogined")=="true"){
          axios({
          url:"http://localhost:8080/search",
          data:{
            name:this.serach_name
          },                //jason
          method:"POST"
        }).then(res=>{
          this.students=res.data;
          })
      }else{
        this.$alert("Please login first!")
      }
    },
    updateresult(re){//响应子组件计算该试验的缺陷预计结果
      this.Results.id=re.id;
      this.Results.name=re.name;
      this.Results.t=re.t;
      this.Results.e=re.e;
      this.Results.l=re.l;
      this.Results.eff=re.eff;
      this.Results.dv.dv1=re.db1;
      this.Results.dv.dv2=re.db2;
      this.Results.dv.dv3=re.db3;
      this.Results.dv.dv4=re.db4;
      this.Results.dv.dv5=re.db5;
      this.Results.dv.dv6=re.db6;

    },
    initEcharts(realdata) {
      // 多列柱状图
      const mulColumnZZTData = {
        title:{
          text: '缺陷发现数据及雷利拟合直方图',
          x:'center',      // 水平安放位置，默认为'left'，可选为：'center' | 'left' | 'right' | {number}（x坐标，单位px）
          y: 'top',
          textStyle: { // 主标题文本样式{"fontSize": 18,"fontWeight": "bolder","color": "#333"}
          fontFamily: 'Arial',
          fontSize: 24,
          fontStyle: 'normal',
          fontWeight: 'normal',
          }
        },
        xAxis: {
          data:["初步设计", "详细设计", "编码", "单元测试", "集成测试", "系统测试"], //横坐标  
        },
        // 图例
        legend: {
          data: ["实际值", "估计值"],
          top: "0%"
        },
        yAxis: {},
        series: [
          {
            type: "bar", //形状为柱状图
            data: [realdata.stage1, realdata.stage2,realdata.stage3,realdata.stage4,realdata.stage5,realdata.stage6],
            name: "人数", // legend属性
            label: {
              // 柱状图上方文本标签，默认展示数值信息
              show: true,
              position: "top"
            }
          },
          {
            type: "bar", //形状为柱状图
            data: [this.Results.dv.dv1, this.Results.dv.dv2,this.Results.dv.dv3,this.Results.dv.dv4,this.Results.dv.dv5,this.Results.dv.dv6],
            name: "任务数", // legend属性
            label: {
              // 柱状图上方文本标签，默认展示数值信息
              show: true,
              position: "top"
            }
          }
        ]
      };
      const myChart = echarts.init(document.getElementById("mychart"));
      myChart.setOption(mulColumnZZTData);
      //随着屏幕大小调节图表
      window.addEventListener("resize", () => {
        myChart.resize();
      });
    }
  },
  computed:{
    student_for_page(){
      return this.students.slice(this.page*5-5,this.page*5);//vue's culculate function "computed"
      //computed 属性用于定义计算属性，即基于其他数据属性计算出的值。计算属性会在其依赖的属性发生变化时自动重新计算，并且结果会被缓存，直到依赖项发生改变。
      //computed 的缓存机制：computed 属性的结果会被缓存，直到其依赖的数据发生变化，这使得它比直接使用方法更高效，尤其是在处理较为复杂的计算时。
      //适合用于基于现有数据进行计算：computed 属性适用于需要从现有的数据中衍生出其他数据的场景，如分页、过滤、排序等
    }
  }
}
</script>

<style>

</style>
